package redisClient

import (
	"encoding/json"
	"fmt"
	"gitee.com/lv_baobao/gcore"
	"gitee.com/lv_baobao/gcore/dbUtils/redisLog"
	"github.com/go-redis/redis"
	"runtime"
	"time"
)

type NormalClient struct {
	Client *redis.Client
}

func NewNormalClient() IRedisClient {
	var normalClient = &NormalClient{}
	normalClient.init()
	return normalClient
}

func (r *NormalClient) init() {
	redisConfig := gcore.NewAppSettingsHelper().GetAppConfig().Redis
	if redisConfig.PoolSize == 0 {
		redisConfig.PoolSize = runtime.NumCPU()
	}
	server := redisConfig.ServerList[0]
	r.Client = redis.NewClient(&redis.Options{
		Addr:     fmt.Sprintf("%s:%d", server.Host, server.Port),
		Password: redisConfig.PassWord,
		PoolSize: redisConfig.PoolSize,
	})
}

func (r *NormalClient) Get(key string, objPtr interface{}) error {
	bytes, err := r.Client.Get(key).Bytes()
	if err != nil {
		return err
	}
	err = json.Unmarshal(bytes, objPtr)
	if err != nil {
		return err
	}
	return nil
}

func (r *NormalClient) Add(key string, value interface{}, duration time.Duration) error {
	bytes, err := json.Marshal(value)
	if err != nil {
		return err
	}
	err = r.Client.Set(key, bytes, duration).Err()
	if err == nil && gcore.NewAppSettingsHelper().GetAppConfig().EnableSyncRedis {
		redisLog.NewRedisLogHelper().WriteLog(redisLog.RedisLogContent{
			LogType:           redisLog.Add,
			RedisKey:          key,
			Content:           value,
			SecondsOfDuration: duration.Seconds(),
		})
	}
	return err
}

func (r *NormalClient) Incr(key string) error {
	err := r.Client.Incr(key).Err()
	if err == nil && gcore.NewAppSettingsHelper().GetAppConfig().EnableSyncRedis {
		redisLog.NewRedisLogHelper().WriteLog(redisLog.RedisLogContent{
			LogType:  redisLog.Incr,
			RedisKey: key,
			Content:  nil,
		})
	}
	return err
}

func (r *NormalClient) Del(key string) error {
	err := r.Client.Del(key).Err()
	if err == nil && gcore.NewAppSettingsHelper().GetAppConfig().EnableSyncRedis {
		redisLog.NewRedisLogHelper().WriteLog(redisLog.RedisLogContent{
			LogType:  redisLog.Del,
			RedisKey: key,
			Content:  nil,
		})
	}
	return err
}

func (r *NormalClient) Expire(key string, duration time.Duration) error {
	err := r.Client.Expire(key, duration).Err()
	if err == nil && gcore.NewAppSettingsHelper().GetAppConfig().EnableSyncRedis {
		redisLog.NewRedisLogHelper().WriteLog(redisLog.RedisLogContent{
			LogType:           redisLog.Expire,
			RedisKey:          key,
			Content:           nil,
			SecondsOfDuration: duration.Seconds(),
		})
	}
	return err
}

func (r *NormalClient) LPush(key string, value interface{}) (error, int64) {
	bytes, err := json.Marshal(value)
	if err != nil {
		return err, 0
	}
	push := r.Client.LPush(key, bytes)
	if push.Err() == nil && gcore.NewAppSettingsHelper().GetAppConfig().EnableSyncRedis {
		redisLog.NewRedisLogHelper().WriteLog(redisLog.RedisLogContent{
			LogType:  redisLog.LPush,
			RedisKey: key,
			Content:  value,
		})
	}
	return push.Err(), push.Val()
}

func (r *NormalClient) LRange(key string, start int64, stop int64) ([]string, error) {
	push := r.Client.LRange(key, start, stop)
	return push.Val(), push.Err()
}

func (r *NormalClient) LIndex(key string, index int64) (string, error) {
	push := r.Client.LIndex(key, index)
	return push.Val(), push.Err()
}

func (r *NormalClient) LSet(key string, index int64, value interface{}) error {
	cmd := r.Client.LSet(key, index, value)
	err := cmd.Err()
	if err == nil && gcore.NewAppSettingsHelper().GetAppConfig().EnableSyncRedis {
		redisLog.NewRedisLogHelper().WriteLog(redisLog.RedisLogContent{
			LogType:  redisLog.LSet,
			RedisKey: key,
			Content:  value,
			Count:    index,
		})
	}
	return err
}

func (r *NormalClient) LRem(key string, count int64, value interface{}) error {
	cmd := r.Client.LRem(key, count, value)
	err := cmd.Err()
	if err == nil && gcore.NewAppSettingsHelper().GetAppConfig().EnableSyncRedis {
		redisLog.NewRedisLogHelper().WriteLog(redisLog.RedisLogContent{
			LogType:  redisLog.LRem,
			RedisKey: key,
			Content:  value,
			Count:    count,
		})
	}
	return err
}

func (r *NormalClient) LTrim(key string, start int64, stop int64) error {
	cmd := r.Client.LTrim(key, start, stop)
	return cmd.Err()
}

func (r *NormalClient) HSet(key string, field string, value interface{}) error {
	bytes, err := json.Marshal(value)
	if err != nil {
		return err
	}
	cmd := r.Client.HSet(key, field, bytes)
	return cmd.Err()
}

func (r *NormalClient) HGet(key string, field string, objPtr interface{}) error {
	cmd := r.Client.HGet(key, field)
	if cmd.Err() != nil {
		return cmd.Err()
	}
	bytes, err := cmd.Bytes()
	if err != nil {
		return err
	}
	err = json.Unmarshal(bytes, objPtr)
	return err
}

//func (r *NormalClient) HGetAll(key string,objPtr interface{}) error {
//	cmd := r.Client.HGetAll(key)
//	if cmd.Err()!=nil{
//		return cmd.Err()
//	}
//	resList, err := cmd.Result()
//	if err != nil {
//		return err
//	}
//	for _, v := range resList {
//	}
//	return err
//}

func (r *NormalClient) Pipeline() redis.Pipeliner {
	return r.Client.Pipeline()
}
